//
//  link_list_make.hpp
//  cpp_algorithm
//
//  Created by 李贺 on 2021/11/26.
//

#ifndef link_list_make_hpp
#define link_list_make_hpp

#include <stdio.h>
#include <vector>
#include <iostream>

using namespace std;

class MyLinkListNode {

public:
    int val;
    MyLinkListNode *next;
    MyLinkListNode (int x): val(x), next(NULL) {
    }
};

class MyLinkList {
    
public:
    int count;
    MyLinkListNode*head;
    
public:
    
    MyLinkList() {
        this->count = 0;
        this->head = NULL;
    }
    
    void addAtHead(MyLinkListNode* node) {
        if (this->count == 0) {
            // 链表为空的时候
            this->head = node;
            this->head->next = NULL;
            this->count++;
        } else {
            //链表非空
            MyLinkListNode*temp = this->head;
            this->head = node;
            node->next = temp;
            this->count++;
        }
    }
    
    void addAtTrail(MyLinkListNode*node) {
        if (this->count == 0) {
            // 链表为空的时候
            this->head = node;
            this->head->next = NULL;
            this->count++;
        } else {
            MyLinkListNode * current = this->head;
            while (current != NULL && current->next != NULL) {
                current = current->next;
            }
            current->next = node;
            this->count++;
        }
    }
    
    void addAtIndex(int index, MyLinkListNode* node) {
        if (this->count == 0) {
            // 链表为空的时候
            this->head = node;
            this->head->next = NULL;
            this->count++;
            return;
        }
        
        if (index <= 0) {
            // 在头部插入
            this->addAtHead(node);
            return;
        }
        
        if (index > this->count - 1) {
            // 在尾部插入
            this->addAtTrail(node);
            return;
        }
        
        MyLinkListNode * current_cousor = this->head;
        MyLinkListNode * pre_cousor = nullptr;
        int temp_index = 0;
        
        while (current_cousor != NULL) {
            if (temp_index == index) {
                pre_cousor->next = node;
                node->next = current_cousor;
                this->count++;
                break;
            } else {
                temp_index++;
                pre_cousor = current_cousor;
                current_cousor = current_cousor->next;
            }
        }
        
    }
    
    MyLinkListNode* getIndex(int index) {
        if (this->count == 0) {
            return nullptr;
        }
        if (index > this->count - 1) {
            return nullptr;
        }
        if (index < 0) {
            return nullptr;
        }
        
        MyLinkListNode *node = this->head;
        int tmep_index = 0;
        while (node != NULL) {
            if (tmep_index == index) {
                return node;
            } else {
                tmep_index++;
                node = node->next;
            }
        }
        return node;
    }
    
    int deleteAtIndex(int index) {
        if (this->count == 0) {
            return -1;
        }
        if (index > this->count - 1) {
            return -1;
        }
        if (index < 0) {
            return -1;
        }
        
        MyLinkListNode *pre_cousor = nullptr;
        MyLinkListNode *current_cousor = this->head;
        int temp_index = 0;
        MyLinkListNode *temp = NULL;
        
        while (current_cousor != NULL) {
            if (temp_index == index) {
                temp = current_cousor;
                pre_cousor->next = current_cousor->next;
                break;
            } else {
                temp_index++;
                pre_cousor = current_cousor;
                current_cousor = current_cousor->next;
            }
        }
        delete temp;
        return 0;
    }
    
    void test() {
        MyLinkList linklist = MyLinkList();
        
        MyLinkListNode *node1 = new MyLinkListNode(99);
        linklist.addAtHead(node1);
        
        
        MyLinkListNode *node2 = new MyLinkListNode(88);
        linklist.addAtTrail(node2);
        
        MyLinkListNode *node3 = new MyLinkListNode(77);
        linklist.addAtIndex(1, node3);
        
        linklist.deleteAtIndex(1);
        
        MyLinkListNode *get = linklist.getIndex(1);
        cout << get->val << "\n";
    }
};

#endif /* link_list_make_hpp */
